home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
dskut
/
chksum2.zip
/
CHKSUM.C
next >
Wrap
C/C++ Source or Header
|
1989-02-16
|
8KB
|
318 lines
/* /usr/bin/src/chksum.c 880118 NHA */
#define DEBUG 0
#define MAJOR 'P'
#define MINOR 'C'
#include <gen.h>
#include <string.h>
#define SUCCESS 0
#define FAILURE (!SUCCESS)
#ifdef __STDC__
import char *gets(void *buffer);
import int open(char *filename, int mode);
import int read(int fd, void *buf, int count);
import int close(int fd);
import char *getenv(char *name);
import void exit(int status);
import unsigned long crc32buf(unsigned long initialSum,
unsigned char *buf, unsigned count);
#else
import char *gets();
import int open();
import int read();
import int close();
import char *getenv();
import void exit();
import unsigned long crc32buf();
#endif __STDC__
local unsigned char buffer[BUFSIZ]; /* reads go into this buffer */
local bool showCount; /* show the byte count [-c] */
local bool showError; /* show Errors in any case */
local bool totalOnly; /* don't show file sums [-t] */
local bool verbose; /* print filenames [-v] */
local bool firstFile; /* only true for 1st file */
local unsigned fileCount; /* # of files processed OK */
local unsigned errorCount; /* # of files with errors */
local unsigned long sum; /* checksum for a file */
local unsigned long grandSum; /* checksum over all files */
local unsigned long byteCount; /* byte count for a file */
local unsigned long grandByteCount; /* byte count over all files */
/*+ c h k s u m
* Calculate two chksums for the file.
* One is simply the chksum of the bytes in the file.
* The other is updating the grandSum with the bytes in the file.
* The grandSum is only updated for files after the first file.
* The byteCount and grandByteCount variables are also updated.
* Return FAILURE for file errors, else SUCCESS.
*/
local bool chksum(fd)
int fd; /* File Descriptor */
{
int status; /* status returned from sys calls */
printd(4, "chksum(%d)\n", fd);
sum = 0L;
while (1)
{
/* read next bufferload from the file */
status = read( fd, buffer, sizeof buffer );
printd(9, "read status=%d\n", status);
if (status < 0)
{
printd(4, "chksum(): returning FAILURE\n");
return FAILURE;
}
if (status == 0)
break; /* End Of File */
/* update checksums */
sum = crc32buf(sum, buffer, (unsigned)status);
if ( ! firstFile )
grandSum = crc32buf(grandSum, buffer, (unsigned)status);
/* update byte counts */
byteCount += (unsigned long)status;
grandByteCount += (unsigned long)status;
printd(8, "sum=%08lx, grandSum=%08lx, byteCount=%ld, grandByteCount=%ld\n",
sum, grandSum, byteCount, grandByteCount);
}
printd(4, "chksum(): returning SUCCESS with sum=%08lx, grandSum=%08lx\n",
sum, grandSum);
return SUCCESS;
}
/*+ s u m F i l e
* Given a filename, calculate the checksum, do any necessary displaying,
* and update all the necessary global variables.
* If the filename is a NULL pointer or a pointer to '\0', we use stdin.
* In the event of file access errors, a sum of 0 is printed.
*/
local void sumFile(filename)
char *filename;
{
int fd; /* File Descriptor */
char name[88];
bool isBad; /* YES for file errors */
printd(4, "sumFile(%s)\n", filename);
byteCount = 0L;
/* open input file. NULL or ptr to '\0' is taken to mean standard input */
if (filename == NULL || filename[0] == '\0')
{
strcpy(name, "--Stdin--");
fd = fileno(stdin);
}
else
{
strcpy(name, filename);
fd = open(filename, O_RDONLY);
if (fd < 0)
{
isBad = YES;
++errorCount;
sum = 0L;
printd(2, "sumFile(%s): can't open file for read\n", filename);
if (showError)
fprintf(stderr, "chksum: can't open \"%s\" for reading\n",
filename);
}
else
isBad = NO;
}
/* calculate the checksum */
if (0 <= fd)
{
if (chksum(fd) == SUCCESS)
{
isBad = NO;
++fileCount;
if (firstFile)
{
grandSum = sum;
firstFile = NO;
}
}
else
{
isBad = YES;
++errorCount;
sum = 0L;
printd(2, "sumFile(%s): error reading file\n", name);
if (showError)
fprintf(stderr, "chksum: error reading file \"%s\"\n",
filename);
}
if (fd != fileno(stdin))
close(fd);
}
/* report the results */
if ( ! totalOnly)
{
printf("%08lx", sum);
if (showCount)
printf(" %10lu", byteCount);
if (verbose)
if (isBad)
printf(" %s *** ERROR ***", name);
else
printf(" %s", name);
putchar('\n');
}
printd(4, "sumFile(): returning\n");
}
/*+ u s a g e
* Spew out the help message.
*/
local void usage()
{
fprintf(stderr, "chksum -- calculate 32-bit checksum for file(s), output to stdout\n");
fprintf(stderr, "Usage: chksum [-cehtv] {file|--|-}...\n");
fprintf(stderr, "-c Count bytes also\n");
fprintf(stderr, "-e give extended Error reports on stderr\n");
fprintf(stderr, "-h Help; give this help message and exit\n");
fprintf(stderr, "-t Total only; don't list sum for each file\n");
fprintf(stderr, "-v Verbose; list filenames along with checksums\n");
fprintf(stderr, "-- take filenames from stdin, 1 name per line\n");
fprintf(stderr, "- take stdin as a file\n");
fprintf(stderr, "Filenames may be mixed with options.\n");
fprintf(stderr, "Exit status is the number of file errors encountered.\n");
exit(1);
} /* usage */
/*+ m a i n
* See usage() for command line parameters.
*/
export int main(ac, av)
int ac;
char **av;
{
char *p;
char line[BUFSIZ]; /* for reading from stdin */
char switchar;
/* initialize */
initdebug(&ac, &av, "/dev/con", "/dev/fifo", "**0");
showCount = NO; /* default is no byte counts */
showError = NO; /* default is no reports on stderr*/
totalOnly = NO; /* default is show all checksums */
verbose = NO; /* default is no filenames */
firstFile = YES; /* no files checksummed yet */
fileCount = 0;
errorCount = 0;
grandSum = 0L;
grandByteCount = 0L;
p = getenv("SWITCHAR");
if (p == NULL)
switchar = '-';
else
switchar = *p;
/* process command line arguments */
for (--ac, ++av ; 0 < ac ; --ac, ++av)
{
printd(7, "main(): ac = %d, *av = '%s'\n", ac, *av);
if (av[0][0] == switchar)
switch (av[0][1])
{
case 'C':
case 'c':
showCount = YES;
break;
case 'E':
case 'e':
showError = YES;
break;
case 'H':
case 'h':
usage();
break;
case 'T':
case 't':
totalOnly = YES;
break;
case 'V':
case 'v':
verbose = YES;
break;
case '-': /* take filenames from stdin */
while (gets(line) != NULL)
sumFile(line);
if (showError && ferror(stdin))
fprintf(stderr, "chksum: error reading standard input\n");
clearerr(stdin);
break;
case '\0':
sumFile(NULL); /* use standard input for file */
break;
default:
fprintf(stderr, "chksum: unknown option %s\n", av[0]);
} /* switch */
else
sumFile(av[0]); /* file */
}
/* put out the Grand Total */
if ((fileCount + errorCount) == 0)
usage(); /* no files specified */
else if ((fileCount + errorCount) == 1)
{ /* one file specified */
if (totalOnly)
{
printf("%08lx", grandSum);
if (showCount)
printf(" %10lu", grandByteCount);
putchar('\n');
}
}
else
{ /* multiple files specified */
if ( ! totalOnly)
{
printf("========");
if (showCount)
printf("============");
putchar('\n');
}
printf("%08lx", grandSum);
if (showCount)
printf(" %10lu", grandByteCount);
if (verbose)
{
if (showCount)
printf(" Grand Totals for %u files", fileCount);
else
printf(" Grand Total for %u files", fileCount);
if (errorCount ==